# Z字形变换：https://leetcode-cn.com/problems/zigzag-conversion/

# 直接模拟，我的解题思路。 感觉比来回循环，上下移动方便。
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        """
            模拟方式解决，创建二维数组
            实际上只有两种运动方式。 向下，向上。
            定义 act < numRows,代表行数。 向下，向上[(1),(-1)]
            动作更改： idx == numRows - 1(最后一行)， idx == 0（第一行）
            遍历： len(s) 次，就是遍历所有元素。
        """

        # 先处理特殊情况： 当 numRows == 1 时，就是一个一维数组，直接返回原字符串
        if numRows == 1:
            return s
            
        sbs = [[] for i in range(numRows)]
        action = [(1, ),(-1, )]
        act, i, index = 1, 0, 0
        while i < len(s):
            # 加入一个元素
            sbs[index].append(s[i])
            i += 1
            # 判断是否改变行为
            if index == numRows - 1 or index == 0:
                act = (act + 1)%2            
            # 计算下一个index
            index = action[act][0] + index
        
        # 将二维数组中的字符元素拼接起来
        str1 = ''
        for row in sbs:
            for char in row:
                str1 += char

        # return ''.join(s for char in row for row in sbs)
        return str1

s = Solution()
rst = s.convert("AB", 1)
print(rst)



# 2021.9.22重新写这题，再次做笔记
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        """
            直接模拟， 建立 numRows 大小的数组二维数组
        """
        # 当为1时， 直接返回
        if numRows == 1: return s

        matrix = [['' for i in range(numRows*(len(s)) // 2 + 1)] for j in range(numRows)]
        # 定义动作： 只有向下 和向 右上移动，两种动作， 周期为 numRows
        action = ((1, 0), (-1, 1))
        # 最初为向下
        sign = 0
        # 定义坐标，初始化
        x, y = -1, 0
        cnt = 0
        for i in range(0, len(s)):
            c = s[i]
            x = action[sign][0] + x
            y = action[sign][1] + y
            # print(x, y)
            matrix[x][y] = c
            # 记录这次行为进行了几次
            cnt += 1
            # 根据需要， 转换行为，向上或向下
            if sign == 0 and cnt % numRows == 0:
                sign = (sign + 1) % 2
                cnt = 1
            elif sign == 1 and cnt % numRows == 0:
                sign = (sign + 1) % 2
                cnt = 1
        # 最后再按要求从 matrix 中取就行了
        
        # for num in matrix:
        #     print(num)
        
        # rst = ''
        # for row in matrix:
        #     rst += ''.join(row)

        # 按照行拼接成字符串，再按照每行进行拼接
        return ''.join(''.join(row) for row in matrix)



# 优化精简
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        """
            直接模拟， 建立 numRows 大小的数组二维数组
            不能确定列，就不要确定列了， 我们只初始化行， 列不管，后期append动态加入（省去了很多 '' 空字符串的添加）
            行 取 numRows 和 len(s) 的最小值
        """
        matrix = [[] for row in range(min(numRows, len(s)))]
        # 1. 定义动作： 只有向下 和向 右上移动，两种动作， 周期为 numRows, 只需要改变 行的行为即可，不需要确定坐标
        action = (1, -1)
        # 最初为向下
        sign = 0
        # 2. 定义坐标，初始化
        x, cnt = -1, 0
        for i in range(0, len(s)):
            x = action[sign] + x
            matrix[x].append(s[i])
            
            # 3. 记录这次行为进行了几次
            cnt += 1
            # 4. 是否转换动作
            if cnt % numRows == 0:
                sign = (sign + 1) % 2
                cnt = 1        

        # 按照行拼接成字符串，再按照每行进行拼接
        return ''.join(''.join(row) for row in matrix)
